<template>
  <div class="directory-tree">
    <!-- 树形控件头部 -->
    <div class="tree-header">
      <h3 class="tree-title">
        <el-icon><FolderOpened /></el-icon>
        目录结构
      </h3>
      <div class="tree-actions">
        <el-button size="small" text @click="expandAll">
          <el-icon><Plus /></el-icon>
          全部展开
        </el-button>
        <el-button size="small" text @click="collapseAll">
          <el-icon><Minus /></el-icon>
          全部收起
        </el-button>
      </div>
    </div>
    
    <!-- 目录树 -->
    <div class="tree-container" v-loading="loading">
      <el-tree
        ref="treeRef"
        :data="treeData"
        :props="treeProps"
        :default-expand-keys="defaultExpandKeys"
        :current-node-key="currentNodeKey"
        node-key="id"
        highlight-current
        accordion
        @node-click="handleNodeClick"
        class="file-tree"
      >
        <template #default="{ node, data }">
          <div class="tree-node">
            <!-- 节点图标 -->
            <el-icon 
              :class="['node-icon', `file-icon-${data.type}`]"
            >
              <Folder v-if="data.type === 'folder'" />
              <Document v-else />
            </el-icon>
            
            <!-- 节点名称 -->
            <span class="node-label" :title="data.name">
              {{ data.name }}
            </span>
            
            <!-- 文件/文件夹统计 -->
            <span class="node-stats" v-if="data.type === 'folder'">
              <el-tag size="small" type="info" effect="plain">
                {{ data.fileCount || 0 }} 文件
              </el-tag>
              <el-tag 
                size="small" 
                type="success" 
                effect="plain"
                v-if="data.subfolderCount > 0"
              >
                {{ data.subfolderCount }} 文件夹
              </el-tag>
            </span>
          </div>
        </template>
      </el-tree>
      
      <!-- 空状态 -->
      <el-empty 
        v-if="!loading && (!treeData || treeData.length === 0)"
        description="暂无目录数据"
        :image-size="100"
      >
        <el-button type="primary" @click="$emit('refresh')">
          <el-icon><Refresh /></el-icon>
          刷新数据
        </el-button>
      </el-empty>
    </div>
    
    <!-- 统计信息 -->
    <div class="tree-footer" v-if="statistics">
      <el-descriptions :column="2" size="small" border>
        <el-descriptions-item label="总文件夹">
          {{ statistics.totalFolders || 0 }}
        </el-descriptions-item>
        <el-descriptions-item label="总文件">
          {{ statistics.totalFiles || 0 }}
        </el-descriptions-item>
      </el-descriptions>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { FolderOpened, Folder, Document, Plus, Minus, Refresh } from '@element-plus/icons-vue'

// 组件接口定义
const emit = defineEmits(['node-click', 'refresh'])
const props = defineProps({
  // 原始树数据
  rawTreeData: {
    type: Object,
    default: () => ({})
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  },
  // 统计信息
  statistics: {
    type: Object,
    default: () => ({})
  },
  // 默认展开的节点
  defaultExpandKeys: {
    type: Array,
    default: () => []
  }
})

// 响应式数据
const treeRef = ref(null)                // 树组件引用
const treeData = ref([])                 // 处理后的树数据
const currentNodeKey = ref(null)         // 当前选中的节点key

// 树组件配置
const treeProps = {
  children: 'children',
  label: 'name',
  disabled: 'disabled'
}

// 计算属性
const hasData = computed(() => treeData.value && treeData.value.length > 0)

// 监听原始数据变化
watch(
  () => props.rawTreeData,
  (newData) => {
    console.log('目录树数据更新:', newData)
    processTreeData(newData)
  },
  { deep: true, immediate: true }
)

/**
 * 处理树数据
 * @param {Object} rawData 原始树数据
 */
function processTreeData(rawData) {
  if (!rawData || typeof rawData !== 'object') {
    treeData.value = []
    return
  }
  
  try {
    const processed = convertToTreeNodes(rawData)
    treeData.value = processed
    console.log('处理后的树数据:', processed)
  } catch (error) {
    console.error('处理树数据时发生错误:', error)
    treeData.value = []
  }
}

/**
 * 将原始数据转换为树节点格式
 * @param {Object} data 原始数据
 * @param {string} parentPath 父路径
 * @returns {Array} 树节点数组
 */
function convertToTreeNodes(data, parentPath = '') {
  const nodes = []
  
  Object.entries(data).forEach(([key, value]) => {
    const currentPath = parentPath ? `${parentPath}/${key}` : key
    const nodeId = generateNodeId(currentPath)
    
    const node = {
      id: nodeId,
      name: key,
      path: currentPath,
      type: value.type || 'folder',
      fileCount: value.fileCount || 0,
      subfolderCount: value.subfolderCount || 0,
      children: []
    }
    
    // 递归处理子节点
    if (value.children && Object.keys(value.children).length > 0) {
      node.children = convertToTreeNodes(value.children, currentPath)
      node.subfolderCount = node.children.length
    }
    
    nodes.push(node)
  })
  
  // 按名称排序
  return nodes.sort((a, b) => a.name.localeCompare(b.name, 'zh-CN'))
}

/**
 * 生成节点ID
 * @param {string} path 节点路径
 * @returns {string} 节点ID
 */
function generateNodeId(path) {
  // 使用路径生成唯一ID
  return 'node_' + btoa(encodeURIComponent(path)).replace(/[^a-zA-Z0-9]/g, '')
}

/**
 * 处理节点点击
 * @param {Object} data 节点数据
 * @param {Object} node 节点对象
 */
function handleNodeClick(data, node) {
  console.log('点击树节点:', data)
  
  // 更新当前选中的节点
  currentNodeKey.value = data.id
  
  // 发送节点点击事件
  emit('node-click', {
    data,
    node,
    path: data.path,
    type: data.type
  })
}

/**
 * 展开所有节点
 */
function expandAll() {
  if (treeRef.value && treeData.value.length > 0) {
    try {
      // 获取所有节点的key
      const allKeys = getAllNodeKeys(treeData.value)
      console.log('展开所有节点，keys:', allKeys)
      
      // 使用Element Plus的API展开所有节点
      for (const key of allKeys) {
        const node = treeRef.value.getNode(key)
        if (node && !node.expanded) {
          node.expand()
        }
      }
      
      ElMessage.success(`已展开所有节点 (${allKeys.length}个)`)
    } catch (error) {
      console.error('展开节点失败:', error)
      ElMessage.error('展开节点失败')
    }
  }
}

/**
 * 收起所有节点
 */
function collapseAll() {
  if (treeRef.value && treeData.value.length > 0) {
    try {
      // 获取所有节点的key
      const allKeys = getAllNodeKeys(treeData.value)
      console.log('收起所有节点，keys:', allKeys)
      
      // 使用Element Plus的API收起所有节点
      for (const key of allKeys) {
        const node = treeRef.value.getNode(key)
        if (node && node.expanded) {
          node.collapse()
        }
      }
      
      ElMessage.success(`已收起所有节点 (${allKeys.length}个)`)
    } catch (error) {
      console.error('收起节点失败:', error)
      ElMessage.error('收起节点失败')
    }
  }
}

/**
 * 获取所有节点的key
 * @param {Array} nodes 节点数组
 * @returns {Array} 所有节点key的数组
 */
function getAllNodeKeys(nodes) {
  const keys = []
  
  function traverse(nodeArray) {
    nodeArray.forEach(node => {
      keys.push(node.id)
      if (node.children && node.children.length > 0) {
        traverse(node.children)
      }
    })
  }
  
  traverse(nodes)
  return keys
}

/**
 * 根据路径定位节点
 * @param {string} path 节点路径
 */
function locateNode(path) {
  if (treeRef.value && path) {
    const nodeId = generateNodeId(path)
    
    // 展开到指定节点
    treeRef.value.setExpanded(nodeId, true)
    
    // 设置当前节点
    nextTick(() => {
      treeRef.value.setCurrentKey(nodeId)
    })
  }
}

// 暴露方法给父组件
defineExpose({
  expandAll,
  collapseAll,
  locateNode
})
</script>

<style scoped>
.directory-tree {
  height: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  background-color: #fff;
}

.tree-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e4e7ed;
  background-color: #fafbfc;
}

.tree-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  display: flex;
  align-items: center;
  gap: 8px;
}

.tree-actions {
  display: flex;
  gap: 8px;
}

.tree-container {
  flex: 1;
  overflow: auto;
  padding: 8px;
}

.file-tree {
  background-color: transparent;
}

.file-tree :deep(.el-tree-node__content) {
  height: auto;
  min-height: 32px;
  padding: 4px 8px;
  border-radius: 4px;
}

.file-tree :deep(.el-tree-node__content:hover) {
  background-color: #f5f7fa;
}

.file-tree :deep(.el-tree-node__content.is-current) {
  background-color: #e6f3ff;
  border-left: 3px solid #409eff;
  font-weight: 500;
  color: #409eff;
}

.file-tree :deep(.is-current .node-icon) {
  color: #409eff;
}

.tree-node {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 8px;
  padding: 2px 0;
}

.node-icon {
  font-size: 16px;
  flex-shrink: 0;
}

.node-label {
  flex: 1;
  font-size: 14px;
  color: #606266;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.node-stats {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.node-stats .el-tag {
  font-size: 11px;
  height: 18px;
  line-height: 16px;
}

.tree-footer {
  padding: 12px 16px;
  border-top: 1px solid #e4e7ed;
  background-color: #fafbfc;
}

/* 文件类型图标颜色 */
.file-icon-folder { color: #e6a23c; }
.file-icon-document { color: #409eff; }
.file-icon-spreadsheet { color: #67c23a; }
.file-icon-presentation { color: #e6a23c; }
.file-icon-image { color: #f56c6c; }
.file-icon-video { color: #909399; }
.file-icon-audio { color: #b88bf8; }
.file-icon-archive { color: #606266; }
.file-icon-code { color: #303133; }
.file-icon-other { color: #c0c4cc; }

/* 空状态样式 */
.el-empty {
  padding: 40px 20px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .tree-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }
  
  .tree-actions {
    align-self: stretch;
    justify-content: space-between;
  }
  
  .node-stats {
    display: none;
  }
}
</style>